/*
 * ESP32 Bluetooth Audio Receiver - Main Program
 *
 * Developed based on ESP-IDF framework using Espressif official interfaces
 * Core audio processing algorithms, hardware adaptation, sound quality optimization are original development
 *
 * Copyright (c) 2025 lianggumei
 *
 * SPDX-License-Identifier: MIT
 */

#include <memory>

#include "audio_processor.hpp"
#include "bluetooth_audio_receiver.hpp"
#include "bt_app_av.h"
#include "bt_app_core.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "nvs_flash.h"

static const char* kTag = "BluetoothAudio";

// Global instances
static std::shared_ptr<AudioProcessor> g_audio_processor;
static std::shared_ptr<BluetoothAudioReceiver> g_bluetooth_receiver;

// I2S write function
void WriteToI2S(const uint8_t* data, size_t len) {
  write_ringbuf(data, len);
}

// Main program entry point
extern "C" void app_main() {
  ESP_LOGI(kTag, "ESP32 Bluetooth Audio Receiver Starting");

  // Initialize NVS
  esp_err_t ret = nvs_flash_init();
  if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
    ESP_ERROR_CHECK(nvs_flash_erase());
    ret = nvs_flash_init();
  }
  ESP_ERROR_CHECK(ret);

  // Create audio processor
  g_audio_processor = std::make_shared<AudioProcessor>();
  if (!g_audio_processor) {
    ESP_LOGE(kTag, "Failed to create audio processor!");
    return;
  }

  // Set I2S writer function
  g_audio_processor->SetI2SWriter(WriteToI2S);

  // Create bluetooth audio receiver
  g_bluetooth_receiver = std::make_shared<BluetoothAudioReceiver>();
  if (!g_bluetooth_receiver) {
    ESP_LOGE(kTag, "Failed to create bluetooth audio receiver!");
    return;
  }

  // Set audio processor
  g_bluetooth_receiver->SetAudioProcessor(g_audio_processor);

  // Initialize I2S task
  ret = bt_i2s_task_start_up();
  if (ret != ESP_OK) {
    ESP_LOGE(kTag, "I2S task startup failed: %s", esp_err_to_name(ret));
    return;
  }

  // Install I2S driver
  bt_i2s_driver_install();

  // Initialize bluetooth audio receiver
  ret = g_bluetooth_receiver->Initialize();
  if (ret != ESP_OK) {
    ESP_LOGE(kTag, "Bluetooth audio receiver initialization failed: %s", esp_err_to_name(ret));
    return;
  }

  // Start bluetooth audio receiver
  ret = g_bluetooth_receiver->Start();
  if (ret != ESP_OK) {
    ESP_LOGE(kTag, "Bluetooth audio receiver startup failed: %s", esp_err_to_name(ret));
    return;
  }

  ESP_LOGI(kTag, "Bluetooth audio receiver started successfully");
  ESP_LOGI(kTag, "Waiting for bluetooth connection...");

  // Main loop
  while (true) {
    vTaskDelay(pdMS_TO_TICKS(1000));
  }
}